<?php

namespace Mall\Controller;

use Common\Controller\ApiController;
use Common\Model\ModelException;
use Payment\Client\Charge;
use Payment\Config;
use Util\ModelUtils;
use Util\StringUtils;
use Util\KdNiao;
use Ruben\ApplePay;
use Ruben\Paypal;
use Ruben\PaypalMobile;
use EasyWeChat\Factory;
use Think\Log;


class OrderController extends ApiController {
    
    /**
     * 自动收货,不用定时器是考虑到服务器性能问题,而且定时器比较合理的做法需要用到rdies的队列，考虑到这个项目的成本问题。
     */
    public function autoreceived() {
       $order = D('Order');
//       $week = $endtime = strtotime(date("Y-m-d H:i:s",strtotime("-7days",strtotime("now")))); //七天前
       $twoweek = $endtime = strtotime(date("Y-m-d H:i:s",strtotime("-15days",strtotime("now")))); //15天前

       $map['delivered_time'] = ['elt',$twoweek];
       $map['status'] ='delivered';
       $list = $order->where($map)->select();
       if($list){
        $data['received_time'] = time();
       $data['status'] = 'received';
        foreach ($list as $value) {
            $data['order_id'] = $value['order_id'];
            $order->save($data);
        }  
       }  
    }

    /**
     * 创建订单
     */
    public function buildOrder() {
        $input = $this->request();
        $user = $this->user;
        $items = $input['items'];
        $addressId = $input['address_id'];
        $isCart = filter($input['is_cart'], 0);
        $uid = filter($input['uid'], null);//网红id
        $itemsDict = array_column($items, null, 'goods_id');

        $skus = array_column($items, 'sku');
        $goodsIds = array_column($items, 'goods_id');
        $dbskus = D('GoodsSku')->where(['name' => ['in', $skus]])->getField('name,stock,price,wholesale_price,id', true);

        if (count($skus) !== count($dbskus)) {
            $this->errorResponse(90118);
        }
        // 库存判断，不作锁处理
        foreach ($items as $item) {
            if ($dbskus[$item['sku']]['stock'] < $item['quantity']) {
                $this->errorResponse(90119);
            }
        }

        if (empty(array_keys($itemsDict))) {
            $this->errorResponse(90003);
        }

        $goodsList = D('Goods')->where(['goods_id' => ['in', array_keys($itemsDict)]])->select();
        if (!D('Goods')->isValid($goodsList)) {
            $this->errorResponse(90004);
        }

        $shopIds = array_column($goodsList, 'shop_id');
        $shops = D('Shop')->where(['shop_id' => ['in', $shopIds]])->select();
        if (!D('Shop')->isValid($shops)) {
            $this->errorResponse(90005);
        }

        /* 嵌入数量及规格到商品信息 */
        $goodsWithSkus = [];
        $goodsList = array_column($goodsList, null, 'goods_id');
        foreach ($items as $item) {
            $goodsWithSkus[] = array_merge($goodsList[$item['goods_id']], [
                'quantity' => $item['quantity'],
                'sku' => $item['sku'],
            ]);
        }


        $goodsList = $goodsWithSkus;
        // array_walk($goodsList, function(&$goods) use ($itemsDict){
        //     $goods['quantity'] = $itemsDict[$goods['goods_id']]['quantity'];
        //     $goods['sku'] = $itemsDict[$goods['goods_id']]['sku'];
        // });

        $itemGroups = array_group($goodsList, 'shop_id');

        $orderTransModel = D('Order');
        $orderTransModel->startTrans();
        /* 收货地址 */
        $receiveAddress = null;
        if ($addressId) {
            $receiveAddress = D('UserAddr')->find($addressId);
        } else {
            $receiveAddress = D('UserAddr')->where(['user_id' => $user['id'], 'is_default' => 1])->find();
        }

        $orderIds = [];
        foreach ($shops as $shop) {
            $itemGroup = $itemGroups[$shop['shop_id']];
            $totalPrice = D('Order')->calcTotalPrice($shop, $itemGroup);
            $order = [
                'order_no' => $this->createOrderNo(),
                'status' => 'unpaid',
                'user_id' => $user['id'],
                'total_price' => $totalPrice,
                'shop_id' => $shop['shop_id'],
                'express_fee' => $shop['express_fee'],
                'uid' => $uid,
            ];
            $orderModel = D('Order');
            if (!$orderModel->create($order)) {
                $orderTransModel->rollback();
                $this->errorResponse(90000, $orderModel->getError());
            }
            $orderId = $orderModel->add();
            //减库存，半小时后未付款就释放
            foreach ($items as $item) {
                D('GoodsSku')->where(['name' =>$item['sku']])->setDec('stock',$item['quantity']);
        }
            
            /* 如果有收货地址设置收货地址 */
            if ($receiveAddress) {
                D('Order')->setReceiveAddress($orderId, $receiveAddress);
            }

            /* 处理订单项 */
            foreach ($itemGroup as $goods) {
                $specs = D('GoodsSpec')->where([
                            'goods_id' => $goods['goods_id'],
                            'id' => ['in', explode(';', $goods['sku'])]
                        ])->getField('id,name,val', true);

                D('OrderGoods')->add(array_merge($goods, [
                    'order_id' => $orderId,
                    'total_price' => $goods['price'] * $goods['quantity'],
                    'photo' => implode(',', $goods['photo']),
                    'sku' => serialize([
                        'id' => $dbskus[$goods['sku']]['id'],
                        'name' => $goods['sku'],
                        'price' => $dbskus[$goods['sku']]['price'],
                        'items' => array_keep($specs, explode(';', $goods['sku'])),
                    ])
                                ]
                ));
            }
            $orderIds[] = $orderId;
        }
        
        if ($isCart == 1) {
            //删除购物车
            D('Cart')->putOut($user['id'], $items);
        }
        $orderTransModel->commit();
        $orders = D('Order')->getOrders($orderIds);
        $orders = transform('Order', 'listview', $orders);
        $this->createdResponse($orders);
    }

    /**
     * 结算订单
     * @return [type] [description]
     */
    public function settle() {
        $input = $this->request();
        $orderIds = explode(",", $input['orderIds']);
        $orders = D('Order')->getOrders($input['orderIds']);
        D('Mall/Goods')->fillGoodsFromSku(array_column_link($orders, 'items'));
        $orders = transform('Order', 'listview', $orders);
        $this->createdResponse($orders);
    }
    /**
     * 订单详情
     */
    public function orderDetails($id) {
        $order = D('Order')->find($id);
        ModelUtils::hasMany($order, ['relation' => 'OrderGoods', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'items']);
        ModelUtils::hasOne($order, ['relation' => 'OrderAddr', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'receive_addr']);
        if (empty($shop_id)) {
            ModelUtils::hasOne($order, ['relation' => 'Shop', 'refKey' => 'shop_id', 'foreignKey' => 'shop_id']);
        }
        if($order['status']=='unpaid'){
         $endtime = strtotime(date("Y-m-d H:i:s",strtotime("+12 hour",(int)$order['create_time'])));
         $order['surplus_time'] = $endtime;
        }

        foreach ($order['items'] as &$value){
            $sku = unserialize($value['sku']);
            $value['selectedSpecs'] = array_values($sku['items']);
            $value['selectedSku'] = array_keep($sku, ['id', 'name', 'price']);
        };
         $orders = transform('Order', 'listview', $order);
        $this->response($order);
    }
    
    /**
     * 确认付款
     */
    public function preparePay() {
        $input = $this->request();
        $channel = $input['channel'];
        $openid = $input['openid'];
        $orderIds = explode(',', $input['order_ids']);
        $user_voucher_id = filter($input['user_voucher_id'], 0);
        $integral = filter($input['integral'], 0);
        $message = filter($input['message'], 0);
        $freight = filter($input['freight'], 0);

      
        $user = D('Users')->find($this->user['id']);

        if ($user['yimei_integral'] < $integral && $integral > 0) {
            $this->errorResponse(90013, '个人积分不足');
        }

        if ($user_voucher_id > 0) {
            $user_voucher = D('UserVoucher')->find($user_voucher_id);
            if ($user_voucher['status'] != 0) {
                $this->errorResponse(90014, '代金券状态异常');
            }
            $voucher = D('Voucher')->find($user_voucher['voucher_id']);
            if ($voucher) {
                $voucher_amount = $voucher['amount'];
            } else {
                $voucher_amount = 0;
            }
        } else {
            $voucher_amount = 0;
        }
        $proportion = M('integralProportion')->find();

        $offset_amount = ($integral * $proportion['integral_proportion']) > 0 ? $integral * $proportion['integral_proportion'] * 100 : 0;


        if (empty($orderIds))
            $this->errorResponse(90008);
        $orders = D('Order')->getOrders($orderIds);

        //发票处理
        $invoice = filter($input['invoice'], 0);

        if ($invoice == 1) {
            $invoice_id = D('Invoice')->add([
                'invoicename' => filter($input['invoicename'], 0),
                'taxnumber' => filter($input['taxnumber'], 0),
                'user_id' => $this->user['id'],
                'create_time' => time(),
            ]);
        }

        foreach ($orders as $order) {
            if ($order['status'] !== 'unpaid') {
                $this->errorResponse(90009);
            }
            if (empty($order['receive_addr'])) {
                $this->errorResponse(90012);
            }

            if ($invoice == 1)
                D('Order')->where(['order_id' => $order['order_id']])->setField('invoice_id', $invoice_id); //插入发票ID
            D('Order')->where(['order_id' => $order['order_id']])->setField('message', $message); //插入发票ID
            D('Order')->where(['order_id' => $order['order_id']])->setField('freight', $freight * 100); //修改运费
        }

        $totalPrice = array_sum(array_column($orders, 'total_price'));
        // 生成支付订单号
        $payOrderNo = 'PAY' . date('YmdHis') . StringUtils::randString(4, 1);
        $amount = $totalPrice - $offset_amount - $voucher_amount + $freight * 100;

        if ($amount <= 0) {
            $this->errorResponse(90120);
        }

        $newid = D('PaymentLog')->add([
            'uid' => $this->user['id'],
            'amount' => $amount,
            'original_amount' => $totalPrice,
            'channel' => $channel,
            'type' => 'shopping',
            'create_time' => time(),
            'status' => 'unpaid',
            'payment_no' => $payOrderNo,
            'order_ids' => $input['order_ids'],
            'remark' => '商城购物,支付单号' . $payOrderNo,
            'user_voucher_id' => $user_voucher_id,
            'integral' => $integral,
            'integral_amount' => $offset_amount,
            'voucher_amount' => $voucher_amount
        ]);
        
        $payData = [
            'body' => '商城支付',
            'subject' => '商城支付',
            'order_no' => $payOrderNo,
            'timeout_express' => time() + 600, // 表示必须 600s 内付款
            'amount' => $amount / 100, // 单位为元 ,最小为0.01
            'return_param' => '',
            'client_ip' => get_client_ip(),
            'goods_type' => '1', // 0 虚拟 1 实体
            'store_id' => '',
            // 说明地址：https     :/ /doc.open.alipay.com/doc2/detail.htm?treeId = 270&articleId = 105901&docType = 1
            // 建议什么也不填
            'qr_mod' => '',
        ];

        // 处理库存
        $orderItemsList = array_column($orders, 'items');
        // dump($orderItemsList);
        foreach ($orderItemsList[0] as $orderItems) {
            $orderItems['sku'] = unserialize($orderItems['sku']);
            D('GoodsSku')->where(['name' => $orderItems['sku']['name']])
                    ->setDec('stock', $orderItems['quantity']);
        }

        switch ($channel) {
            case 'ali_web':
            case 'ali_wap':
                $config = C('sdk.alipay');
                try {
                    $redirectUrl = Charge::run($channel, $config, $payData);
                    $this->createdResponse(['redirect_url' => $redirectUrl]);
                } catch (PayException $e) {
                    $this->errorResponse(10015, $e->getMessage());
                }
                break;
            case 'ali_app':
                $config = C('sdk.alipay');
                try {
                    $ret = Charge::run($channel, $config, $payData);
                    $this->createdResponse(['param_str' => $ret, 'channel' => 'alipay']);
                } catch (PayException $e) {
                    $this->errorResponse(10015, $e->getMessage());
                }
                break;
            case 'coin':
                // 模拟回调参数
                $callbackData = [
                    'order_no' => $payOrderNo,
                    'transaction_id' => date('Ymd') . $this->user['id'] . StringUtils::randString(10, 1),
                ];
                try {
                    D('Payment/PaymentLog')->deal($callbackData);
                    $this->createdResponse();
                } catch (ModelException $e) {
                    $this->errorModelResponse($e);
                }
                break;
            case 'wx_app':
                $config = C('sdk.wxpay');
                try {
                    $ret = Charge::run($channel, $config, $payData);
                    $ret['packages'] = $ret['package'];
                    $this->createdResponse(['param_obj' => $ret, 'channel' => 'wxpay']);
                } catch (PayException $e) {
                    throw $e;
                }
                break;
            case 'wx_qr':
                $config = C('sdk.wxpay');
                $payData['product_id'] = 1;

                try {
                    $ret = Charge::run($channel, $config, $payData);
                    $ret['packages'] = $ret['package'];
                    $this->createdResponse(['param_obj' => $ret, 'channel' => 'wxpay']);
                } catch (PayException $e) {
                    throw $e;
                }
                break;
            case 'wx_pub':
                $config = C('sdk.wxpay_pub');
                $pubData = [
                    'body' => '商城支付',
                    'subject' => "商城支付," . ($amount / 100) . "元",
                    'order_no' => $payOrderNo,
                    'timeout_express' => time() + 600, // 表示必须 600s 内付款
                    'amount' => $amount / 100, // 单位为元 ,最小为0.01
                    'return_param' => '',
                    'client_ip' => get_client_ip(),
                    'openid' => $openid,
                ];
                $ret = Charge::run($channel, $config, $pubData);
                //Log::record(json_encode($ret),'wxpay_pub',TRUE);
                $ret['packages'] = $ret['package'];
                $this->createdResponse(['param_obj' => $ret, 'channel' => 'wxpay']);
                $this->response($ret);
                break;
            default:
                $this->errorResponse(10014);
                break;
        }
    }
    
    public function callbackpay() {
        $input = $this->request();
        $order_no = $input['order_no']?$input['order_no']:NULL;
        $payment_id = filter($input['payment_id'],'');
        if(!empty($order_no)){
            $callbackData = [
                    'order_no' => $order_no,
                    'transaction_id' => date('Ymd') . $this->user['id'] . StringUtils::randString(10, 1),
                    'payment_id' => $payment_id
                ];
                try {
                    D('Payment/PaymentLog')->deal($callbackData);
                    $this->createdResponse();
                } catch (ModelException $e) {
                    $this->errorModelResponse($e);
                }
            
        }else{
           $this->errorResponse('110022', $msg); 
        }
        
    }

    public function paypalToken() {
        $url = 'https://api.sandbox.paypal.com/v1/oauth2/token';
        $header = array();
        $header[] = 'Accept:application/json';
        $header[] = 'Accept-Language:en_US';
        $header[] = "Authorization:BasicAbGlVE3N-ba6IUTcu9ZzUu4i25RNv5_VewA4zBdUZxBW2-lxRqshDD1KTl780MLu6Ob5tov6jerWwjTv:EBMAmR4ImroQt5nMGtl6WI2HYJhhxxQSBXaSlUVKZ8OpT5Vahpba2UX_MOO-K9pQq3vY4bSfr4YkB0aY"; 
        $requestString = "grant_type:client_credentials";

            $con = curl_init((string)$url);
            curl_setopt($con, CURLOPT_HEADER, true);
            curl_setopt($con,CURLOPT_HTTPHEADER,$header);
            curl_setopt($con, CURLOPT_POSTFIELDS, $requestString);
            curl_setopt($con, CURLOPT_POST,true);
            curl_setopt($con, CURLOPT_RETURNTRANSFER,true);
            curl_setopt($con, CURLINFO_HEADER_OUT, true);
            curl_setopt($con, CURLOPT_URL, $url);
            $result = curl_exec($con); 
            echo curl_getinfo($ch, CURLINFO_HEADER_OUT);            
            print_r($result);  
            
        $postData = array("grant_type"=>"client_credentials");    
//        $postData = array("title"=>"测试","content"=>"this is a test","publish"=>"发布");
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST,1);
        curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$postData);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        $output = curl_exec($ch);
        curl_close($ch);
           
        print_r($output);
    }
    public function orderCounter() {
         //先自动执行确认收货
        $this->autoreceived();
        
        $user = $this->user;
        $counters = [
            'unpaid' => 0,
            'paid' => 0,
            'delivered' => 0,
            'received' => 0,
        ];
        $records = D('Order')->field('count(order_id) as `counter`,status')->where(['user_id' => $user['id']])->group('status')->select();
        $records = array_column($records, null, 'status');
        foreach ($counters as $key => $counter) {
            $counters[$key] = $records[$key]['counter'] ? : '0';
        }
        $this->response($counters);
    }

    private function _unifiedorder($channel, $pubData) {
        switch ($channel) {
            case 'ali_web':
            case 'ali_wap':
                $config = C('sdk.alipay');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                    'goods_type' => '1',
                    'store_id' => '',
                    // 说明地址：https://doc.open.alipay.com/doc2/detail.htm?treeId=270&articleId=105901&docType=1
                    // 建议什么也不填
                    'qr_mod' => '',
                ];

                try {
                    $redirectUrl = Charge::run($channel, $config, $payData);
                    return ['redirect' => $redirectUrl];
                } catch (PayException $e) {
                    throw $e;
                }
            case 'ali_app':
                $config = C('sdk.alipay');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                    'goods_type' => 0, // 0 虚拟 1 实体
                        // 'product_id' => $pubData['product_id'],
                        // 'openid' => $pubData['openid'],
                ];
                $ret = Charge::run($channel, $config, $payData);
                return ['param_str' => $ret, 'channel' => 'alipay'];
                break;
            case 'wx_pub':
                $config = C('sdk.wxpay_pub');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                    // 'product_id' => $pubData['product_id'],
                    'openid' => $pubData['openid'],
                ];
                try {
                    $ret = Charge::run($channel, $config, $payData);
                    return ['payment' => $ret, 'channel' => 'wxpay'];
                } catch (PayException $e) {
                    throw $e;
                }
                break;
            case 'wx_app':
                $config = C('sdk.wxpay');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                        // 'product_id' => $pubData['product_id'],
                        // 'openid' => $pubData['openid'],
                ];
                try {
                    $ret = Charge::run($channel, $config, $payData);
                    $ret['packages'] = $ret['package'];
                    return ['param_obj' => $ret, 'channel' => 'wxpay'];
                } catch (PayException $e) {
                    throw $e;
                }
                break;
            case 'wx_wap':
                $config = C('sdk.wxpay');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                        // 'product_id' => $pubData['product_id'],
                        // 'openid' => $pubData['openid'],
                ];
                try {
                    $ret = Charge::run($channel, $config, $payData);
                    $ret['packages'] = $ret['package'];
                    return ['param_obj' => $ret, 'channel' => 'wxpay'];
                } catch (PayException $e) {
                    throw $e;
                }
                break;
            case 'wx_qr':
                $config = C('sdk.wxpay');
                $payData = [
                    'body' => $pubData['body'],
                    'subject' => $pubData['subject'],
                    'order_no' => $pubData['order_no'],
                    'timeout_express' => $pubData['timeout_express'], // 表示必须 600s 内付款
                    'amount' => $pubData['amount'], // 单位为元 ,最小为0.01
                    'return_param' => $pubData['return_param'],
                    'client_ip' => $pubData['client_ip'],
                    'product_id' => $pubData['product_id'],
                ];
                try {
                    $codeUrl = Charge::run($channel, $config, $payData);
                    return ['code_url' => $codeUrl, 'order_no' => $pubData['order_no']];
                } catch (PayException $e) {
                    throw $e;
                }

            default:
                break;
        }
    }

    public function changeReceiveAddress() {
        $input = $this->request();
        $orderIds = explode(',', $input['order_ids']);
        if (empty($orderIds))
            $this->errorResponse(90013);
        $orders = D('Order')->where(['order_id' => ['in', $orderIds]])->select();
        if (empty($orders))
            $this->errorResponse(90008);
        foreach ($orders as $order) {
            if (!in_array($order['status'], ['unpaid']))
                $this->errorResponse(90010);
            if ($order['user_id'] !== $this->user['id'])
                $this->errorResponse(90011);
        }
        $address = D('UserAddr')->find($input['address_id']);
        if (empty($address))
            $this->errorResponse(30012);
        if ($address['user_id'] != $this->user['id'])
            $this->errorResponse(30012);

        foreach ($orderIds as $orderId) {
            $orderAddr = D('OrderAddr')->getByOrderId($orderId);
            if ($orderAddr) {
                D('OrderAddr')->where(['order_id' => $orderId])->setField([
                    'province' => $address['province'],
                    'city' => $address['city'],
                    'district' => $address['district'],
                    'detail' => $address['detail'],
                    'name' => $address['name'],
                    'mobile' => $address['mobile'],
                ]);
            } else {
                D('OrderAddr')->add([
                    'province' => $address['province'],
                    'city' => $address['city'],
                    'district' => $address['district'],
                    'detail' => $address['detail'],
                    'name' => $address['name'],
                    'mobile' => $address['mobile'],
                    'order_id' => $orderId,
                ]);
            }
        }
        $orderAddr = D('OrderAddr')->getByOrderId($orderIds[0]);
        $orderAddr = transform('OrderAddr', 'listview', $orderAddr);
        $this->response($orderAddr);
    }

    /**
     * 确认收货
     *
     * @param int $id 订单ID
     * @return void
     */
    public function receiveOrder() {
        $id = I('get.id');
        $order = D('Order')->where(['user_id' => $this->user['id'], 'order_id' => $id, 'status' => 'delivered'])->find();
        if ($order) {
            $order['received_time'] = time();
            $order['status'] = 'received';
            D('Order')->save($order);
            $userId = M('Shop')->where(['shop_id' => $order['shop_id']])->getField('user_id');
            // 无结算价
            D('Account/Users')->earnMoney($userId, 'sold', $order['total_price'], '卖出商品', true, 0, $id);
            $this->modifySuccessResponse();
        } else {
            $this->errorResponse(90014);
        }
    }

    /**
     * 取消订单
     *
     * @param int $id 订单ID
     * @return void
     */
    public function cancelOrder($id) {
        $order = D('Order')->where(['user_id' => $this->user['id'], 'order_id' => $id, 'status' => 'unpaid'])->find();
        if ($order) {
            $order['cancel_time'] = time();
            $order['status'] = 'cancel';
            D('Order')->save($order);
            $this->modifySuccessResponse();
        } else {
            $this->errorResponse(90014);
        }
    }

    /**
     * 隐藏订单
     *
     * @param int $id 订单ID
     * @return void
     */
    public function hideOrder() {
        $id = I('get.id');
        $order = D('Order')->where(['user_id' => $this->user['id'], 'order_id' => $id, 'status' => 'received', 'is_hide' => 0])->find();
        if ($order) {
            $order['is_hide'] = 1;
            D('Order')->save($order);
            $this->modifySuccessResponse();
        } else {
            $this->errorResponse(90014);
        }
    }

    public function getOrders() {
       
        $input = $this->request();
        $keyword = filter($input['keyword'], '');
        $shop_id = filter($input['shop_id'], null);
        $role = filter($input['role'], 1);
        $status = filter($input['status'], 'unpaid');
        $page = filter($input['page'], 1);
        $perPage = filter($input['pre_page'], 10);
        $perPage > 30 && $perPage = 30;
        $orderby = filter($input['orderby'], 'paid_time');
        $direction = filter($input['direction'], 'desc');
        $stime = filter($input['stime'], 0);
        $etime = filter($input['etime'], time());

        $where['user_id'] = $this->user['id']; //h5端用户买家获取下单记录


        $where['create_time'] = ['between', [$stime, $etime]];

        if ($status !== '') {
            $where['_complex'][] = [
                'status' => $status,
            ];
        }

        if ($keyword !== '') {
            $ids = D('Order')->scope('valid')->where($where)->getField('order_id', true);
            if ($ids) {
                $orderIds = D('OrderGoods')->scope('valid')->where([
                            'title' => ['like', "%{$keyword}%"],
                            'order_id' => ['in', $ids]
                        ])->getField('order_id', true);
            }
            $where['_complex'][] = [
                'order_id' => ['in', $orderIds ? : [0]],
                'order_no' => $keyword,
                '_logic' => 'or',
            ];
        }
        $count = D('Order')->scope('valid')->where($where)->count();
        $orders = D('Order')
                ->scope('valid')
                ->where($where)
                ->page($page, $perPage)
                ->order("{$orderby} {$direction},create_time desc")
                ->select();
        ModelUtils::hasMany($orders, ['relation' => 'OrderGoods', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'items']);
        ModelUtils::hasOne($orders, ['relation' => 'OrderAddr', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'receive_addr']);
        if (empty($shop_id)) {
            ModelUtils::hasOne($orders, ['relation' => 'Shop', 'refKey' => 'shop_id', 'foreignKey' => 'shop_id']);
        }
     
        D('Mall/Goods')->fillGoodsFromSku(array_column_link($orders, 'items'));
        $orders = transform('Order', 'listview', $orders);
        $pagination = pagination($count, $perPage, $page);
        $this->response($orders, $pagination);
    }

    public function getExpressInfo($orderId) {
        $order = D('Order')->where(['order_id' => $orderId, 'user_id' => $this->user['id']])->find();
        if ($order) {
            if (in_array($order['status'], ['received', 'delivered'])) {
                ModelUtils::hasMany($order, ['relation' => 'OrderGoods', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'items']);
                ModelUtils::hasOne($order, ['relation' => 'OrderAddr', 'refKey' => 'order_id', 'foreignKey' => 'order_id', 'name' => 'receive_addr']);
                ModelUtils::hasOne($order, ['relation' => 'Shop', 'refKey' => 'shop_id', 'foreignKey' => 'shop_id']);
                $order = transform('Order', 'listview', $order);
                $config = C('sdk.kdniao');
                $kdniao = new KdNiao($config);
                $express = $kdniao->getOrderTransByNum($order['express_no']);
                $this->response([
                    'order' => $order,
                    'express' => array_keep($express, ['ShipperCode', 'ShipperName', 'Traces', 'State']),
                ]);
            } else {
                $this->errorResponse(90015);
            }
        } else {
            $this->errorResponse(90014);
        }
    }

    private function createOrderNo() {
        return 'PKS2' . date('YmdHis') . StringUtils::randString(4, 1);
    }
    
    public function orderStatistics() {
        
       $Order = D('Order');
       $sql = "SELECT count(*) as total_num,
                SUM(CASE WHEN status='unpaid' THEN 1 ELSE 0 END) as unpaidSum,
                SUM(CASE WHEN status='paid' THEN 1  ELSE 0 END) as paidSum,
                SUM(CASE WHEN status='delivered' THEN 1 ELSE 0 END) as deliveredSum,
                SUM(CASE WHEN status='received' THEN 1 ELSE 0 END) as receivedSum
                FROM bao_order WHERE user_id = {$this->user[id]}";
        $list = $Order->query($sql);
        $this->response($list[0]);
        
    }
}
